package com.softsec.isc.apkextract;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class apkExtractor {
	
	public static Logger logger = LogManager.getLogger(apkExtractor.class);
	private static int JSize1 = -1;
	@SuppressWarnings("unused")
	private static int JSize2 = -1;
	private static int JSize3 = -1;
	
	public static void  main(String[] argv) {
		
		InputStream a = getDexInputStream("K:\\Desktop\\angrybirds_signed.apk");
		byte data1[] = new byte[JSize1]; 
		try {
			 a.read(data1, 0, JSize1);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			try {
				a.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		logger.info("InputStream Read Size: " + new String(data1).length());
		
//		DataInputStream b = getDexDataInputStream("K:\\Desktop\\angrybirds_signed.apk");
//		byte data2[] = new byte[JSize2]; 
//		try {
//			b.read(data2, 0, JSize2);
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		} finally{
//			try {
//				b.close();
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
//		logger.info("DataInputStream Read Size: " + new String(data2).length());
		
		
		DataInputStream c = getDexDataInputStreamWithBuffered("K:\\Desktop\\angrybirds_signed.apk");
		byte data3[] = new byte[JSize3]; 
		try {
			 c.read(data3, 0, JSize3);
//			for (int i = 0; i < 10; i++) {
//				byte[] testStr = new byte[5];
//				logger.info(c.markSupported());
//				c.mark(0);
//				c.read(testStr, 0, 4);
//				c.reset();
//				logger.info(new String(testStr));
//			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			try {
				c.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		logger.info("DataInputStream Read Size: " + new String(data3).length());
		
	}
	@SuppressWarnings({ "resource", "unused" })
	private static byte[] getDex(String filePathString) {
		JarFile jarFile;
		try {
			jarFile = new JarFile(filePathString);
			Enumeration<JarEntry> entries = jarFile.entries();
			while (entries.hasMoreElements()) {
				final JarEntry je = entries.nextElement();
				if (je.getName().contains("classes.dex")) {
					logger.info(je.getSize());
					int fileSize = (int)je.getSize();
					byte data[] = new byte[fileSize]; 
					 InputStream is = new BufferedInputStream(jarFile.getInputStream(je));
					 is.read(data, 0, fileSize);
					 return data;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("resource")
	private static InputStream getDexInputStream(String filePathString) {
		JarFile jarFile;
		try {
			jarFile = new JarFile(filePathString);
			Enumeration<JarEntry> entries = jarFile.entries();
			while (entries.hasMoreElements()) {
				final JarEntry je = entries.nextElement();
				if (je.getName().contains("classes.dex")) {
					logger.info("InputStream way: " + je.getSize());
					JSize1 = (int)je.getSize();
					InputStream is = new BufferedInputStream(jarFile.getInputStream(je));
					 return is;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings({ "resource", "unused" })
	private static DataInputStream getDexDataInputStream(String filePathString) {
		JarFile jarFile;
		try {
			jarFile = new JarFile(filePathString);
			Enumeration<JarEntry> entries = jarFile.entries();
			while (entries.hasMoreElements()) {
				final JarEntry je = entries.nextElement();
				if (je.getName().contains("classes.dex")) {
					logger.info("DataInputStream way: " + je.getSize());
					JSize2 = (int)je.getSize();
					DataInputStream dis = new DataInputStream(jarFile.getInputStream(je));
					 return dis;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("resource")
	private static DataInputStream getDexDataInputStreamWithBuffered(String filePathString) {
		JarFile jarFile;
		try {
			jarFile = new JarFile(filePathString);
			Enumeration<JarEntry> entries = jarFile.entries();
			while (entries.hasMoreElements()) {
				final JarEntry je = entries.nextElement();
				if (je.getName().contains("classes.dex")) {
					logger.info("DataInputStream way: " + je.getSize());
					JSize3 = (int)je.getSize();
					DataInputStream dis = new DataInputStream(new BufferedInputStream(jarFile.getInputStream(je)));
					 return dis;
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
